{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<!--\n",
    "    Licensed to the Apache Software Foundation (ASF) under one\n",
    "    or more contributor license agreements.  See the NOTICE file\n",
    "    distributed with this work for additional information\n",
    "    regarding copyright ownership.  The ASF licenses this file\n",
    "    to you under the Apache License, Version 2.0 (the\n",
    "    \"License\"); you may not use this file except in compliance\n",
    "    with the License.  You may obtain a copy of the License at\n",
    "\n",
    "      http://www.apache.org/licenses/LICENSE-2.0\n",
    "\n",
    "    Unless required by applicable law or agreed to in writing,\n",
    "    software distributed under the License is distributed on an\n",
    "    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n",
    "    KIND, either express or implied.  See the License for the\n",
    "    specific language governing permissions and limitations\n",
    "    under the License.\n",
    "-->\n",
    "\n",
    "# Interactive Beam Examples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import apache_beam as beam\n",
    "from apache_beam.runners.interactive import interactive_runner"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
       " -->\n",
       "<!-- Title: G Pages: 1 -->\n",
       "<svg width=\"194pt\" height=\"218pt\"\n",
       " viewBox=\"0.00 0.00 193.60 218.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 214)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-214 189.596,-214 189.596,4 -4,4\"/>\n",
       "<!-- leaf2468 -->\n",
       "<!-- leaf2469 -->\n",
       "<!-- Create -->\n",
       "<g id=\"node3\" class=\"node\"><title>Create</title>\n",
       "<ellipse fill=\"none\" stroke=\"blue\" cx=\"96.5963\" cy=\"-192\" rx=\"33.5952\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"96.5963\" y=\"-188.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"blue\">Create</text>\n",
       "</g>\n",
       "<!-- Square -->\n",
       "<g id=\"node4\" class=\"node\"><title>Square</title>\n",
       "<ellipse fill=\"none\" stroke=\"blue\" cx=\"50.5963\" cy=\"-105\" rx=\"35.194\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"50.5963\" y=\"-101.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"blue\">Square</text>\n",
       "</g>\n",
       "<!-- Create&#45;&gt;Square -->\n",
       "<g id=\"edge4\" class=\"edge\"><title>Create&#45;&gt;Square</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M83.5132,-175.21C79.0649,-169.393 74.2897,-162.607 70.5963,-156 66.4908,-148.655 62.8,-140.295 59.7398,-132.541\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"63.0108,-131.296 56.2171,-123.166 56.4581,-133.758 63.0108,-131.296\"/>\n",
       "<g id=\"a_edge4&#45;label\"><a xlink:title=\"{8, 6, 1, 9, 7, 0, 4, 5, 3, 2}\">\n",
       "<text text-anchor=\"middle\" x=\"90.5963\" y=\"-144.8\" font-family=\"Times,serif\" font-size=\"14.00\">{8, ...}</text>\n",
       "</a>\n",
       "</g>\n",
       "</g>\n",
       "<!-- Cube -->\n",
       "<g id=\"node5\" class=\"node\"><title>Cube</title>\n",
       "<ellipse fill=\"none\" stroke=\"blue\" cx=\"137.596\" cy=\"-105\" rx=\"29.4969\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"137.596\" y=\"-101.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"blue\">Cube</text>\n",
       "</g>\n",
       "<!-- Create&#45;&gt;Cube -->\n",
       "<g id=\"edge2\" class=\"edge\"><title>Create&#45;&gt;Cube</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M104.697,-174.207C110.575,-162.021 118.631,-145.318 125.301,-131.491\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"128.46,-132.997 129.652,-122.469 122.155,-129.956 128.46,-132.997\"/>\n",
       "<g id=\"a_edge2&#45;label\"><a xlink:title=\"{8, 6, 1, 9, 7, 0, 4, 5, 3, 2}\">\n",
       "<text text-anchor=\"middle\" x=\"138.596\" y=\"-144.8\" font-family=\"Times,serif\" font-size=\"14.00\">{8, ...}</text>\n",
       "</a>\n",
       "</g>\n",
       "</g>\n",
       "<!-- Square&#45;&gt;leaf2469 -->\n",
       "<g id=\"edge3\" class=\"edge\"><title>Square&#45;&gt;leaf2469</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M48.775,-86.799C47.5429,-75.1626 45.8896,-59.5479 44.4802,-46.2368\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"47.9485,-45.7513 43.4149,-36.1754 40.9874,-46.4884 47.9485,-45.7513\"/>\n",
       "<g id=\"a_edge3&#45;label\"><a xlink:title=\"{36, 1, 9, 25, 81, 64, 49, 16, 4, 0}\">\n",
       "<text text-anchor=\"middle\" x=\"69.5963\" y=\"-57.8\" font-family=\"Times,serif\" font-size=\"14.00\">{36, ...}</text>\n",
       "</a>\n",
       "</g>\n",
       "</g>\n",
       "<!-- Cube&#45;&gt;leaf2468 -->\n",
       "<g id=\"edge1\" class=\"edge\"><title>Cube&#45;&gt;leaf2468</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M138.608,-86.799C139.293,-75.1626 140.211,-59.5479 140.994,-46.2368\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"144.493,-46.3637 141.586,-36.1754 137.505,-45.9526 144.493,-46.3637\"/>\n",
       "<g id=\"a_edge1&#45;label\"><a xlink:title=\"{27, 729, 64, 343, 512, 125, 0, 1, 8, 216}\">\n",
       "<text text-anchor=\"middle\" x=\"162.596\" y=\"-57.8\" font-family=\"Times,serif\" font-size=\"14.00\">{27, ...}</text>\n",
       "</a>\n",
       "</g>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Running..."
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Using 0 cached PCollections\n",
       "Executing 8 of 3 transforms."
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Cube produced {27, 729, 64, 343, 512, ...}"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Square produced {36, 1, 9, 25, 81, ...}"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Create produced {8, 6, 1, 9, 7, ...}"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "p = beam.Pipeline(interactive_runner.InteractiveRunner())\n",
    "init_pcoll = p |  beam.Create(range(10))\n",
    "squares = init_pcoll | 'Square' >> beam.Map(lambda x: x*x)\n",
    "cubes = init_pcoll | 'Cube' >> beam.Map(lambda x: x**3)\n",
    "result = p.run()\n",
    "result.wait_until_finish()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "init_list = list(range(10))\n",
    "squares_list = list(result.get(squares))\n",
    "cubes_list = list(result.get(cubes))\n",
    "\n",
    "squares_list.sort()\n",
    "cubes_list.sort()\n",
    "\n",
    "!pip install matplotlib\n",
    "\n",
    "%matplotlib inline\n",
    "from matplotlib import pyplot as plt\n",
    "plt.scatter(init_list, squares_list, label='squares', color='red')\n",
    "plt.scatter(init_list, cubes_list, label='cubes', color='blue')\n",
    "plt.legend(loc='upper left')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class AverageFn(beam.CombineFn):\n",
    "  def create_accumulator(self):\n",
    "    return (0.0, 0)\n",
    "\n",
    "  def add_input(self, sum_count, input):\n",
    "    (sum, count) = sum_count\n",
    "    return sum + input, count + 1\n",
    "\n",
    "  def merge_accumulators(self, accumulators):\n",
    "    sums, counts = zip(*accumulators)\n",
    "    return sum(sums), sum(counts)\n",
    "\n",
    "  def extract_output(self, sum_count):\n",
    "    (sum, count) = sum_count\n",
    "    return sum / count if count else float('NaN')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
       "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
       " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
       "<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
       " -->\n",
       "<!-- Title: G Pages: 1 -->\n",
       "<svg width=\"284pt\" height=\"305pt\"\n",
       " viewBox=\"0.00 0.00 284.34 305.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
       "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 301)\">\n",
       "<title>G</title>\n",
       "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-301 280.339,-301 280.339,4 -4,4\"/>\n",
       "<!-- leaf7582 -->\n",
       "<!-- Square -->\n",
       "<g id=\"node2\" class=\"node\"><title>Square</title>\n",
       "<ellipse fill=\"none\" stroke=\"grey\" cx=\"107.594\" cy=\"-192\" rx=\"35.194\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"107.594\" y=\"-188.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"gray\">Square</text>\n",
       "</g>\n",
       "<!-- Average Square -->\n",
       "<g id=\"node5\" class=\"node\"><title>Average Square</title>\n",
       "<ellipse fill=\"none\" stroke=\"blue\" cx=\"67.594\" cy=\"-105\" rx=\"67.6881\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"67.594\" y=\"-101.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"blue\">Average Square</text>\n",
       "</g>\n",
       "<!-- Square&#45;&gt;Average Square -->\n",
       "<g id=\"edge2\" class=\"edge\"><title>Square&#45;&gt;Average Square</title>\n",
       "<path fill=\"none\" stroke=\"red\" d=\"M99.6913,-174.207C94.085,-162.293 86.4474,-146.063 80.0289,-132.424\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" points=\"83.0421,-130.607 75.6172,-123.049 76.7084,-133.588 83.0421,-130.607\"/>\n",
       "<g id=\"a_edge2&#45;label\"><a xlink:title=\"{36, 1, 9, 25, 81, 64, 49, 16, 4, 0}\">\n",
       "<text text-anchor=\"middle\" x=\"113.594\" y=\"-144.8\" font-family=\"Times,serif\" font-size=\"14.00\">{36, ...}</text>\n",
       "</a>\n",
       "</g>\n",
       "</g>\n",
       "<!-- leaf7574 -->\n",
       "<!-- Create -->\n",
       "<g id=\"node4\" class=\"node\"><title>Create</title>\n",
       "<ellipse fill=\"none\" stroke=\"grey\" cx=\"152.594\" cy=\"-279\" rx=\"33.5952\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"152.594\" y=\"-275.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"gray\">Create</text>\n",
       "</g>\n",
       "<!-- Create&#45;&gt;Square -->\n",
       "<g id=\"edge3\" class=\"edge\"><title>Create&#45;&gt;Square</title>\n",
       "<path fill=\"none\" stroke=\"grey\" d=\"M139.447,-262.245C134.993,-256.432 130.23,-249.639 126.594,-243 122.624,-235.751 119.118,-227.499 116.233,-219.818\"/>\n",
       "<polygon fill=\"grey\" stroke=\"grey\" points=\"119.456,-218.434 112.812,-210.181 112.859,-220.776 119.456,-218.434\"/>\n",
       "<g id=\"a_edge3&#45;label\"><a xlink:title=\"{8, 6, 1, 9, 7, 0, 4, 5, 3, 2}\">\n",
       "<text text-anchor=\"middle\" x=\"146.594\" y=\"-231.8\" font-family=\"Times,serif\" font-size=\"14.00\">{8, ...}</text>\n",
       "</a>\n",
       "</g>\n",
       "</g>\n",
       "<!-- Cube -->\n",
       "<g id=\"node6\" class=\"node\"><title>Cube</title>\n",
       "<ellipse fill=\"none\" stroke=\"grey\" cx=\"193.594\" cy=\"-192\" rx=\"29.4969\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"193.594\" y=\"-188.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"gray\">Cube</text>\n",
       "</g>\n",
       "<!-- Create&#45;&gt;Cube -->\n",
       "<g id=\"edge6\" class=\"edge\"><title>Create&#45;&gt;Cube</title>\n",
       "<path fill=\"none\" stroke=\"grey\" d=\"M160.694,-261.207C166.572,-249.021 174.629,-232.318 181.298,-218.491\"/>\n",
       "<polygon fill=\"grey\" stroke=\"grey\" points=\"184.458,-219.997 185.65,-209.469 178.153,-216.956 184.458,-219.997\"/>\n",
       "<g id=\"a_edge6&#45;label\"><a xlink:title=\"{8, 6, 1, 9, 7, 0, 4, 5, 3, 2}\">\n",
       "<text text-anchor=\"middle\" x=\"194.594\" y=\"-231.8\" font-family=\"Times,serif\" font-size=\"14.00\">{8, ...}</text>\n",
       "</a>\n",
       "</g>\n",
       "</g>\n",
       "<!-- Average Square&#45;&gt;leaf7582 -->\n",
       "<g id=\"edge1\" class=\"edge\"><title>Average Square&#45;&gt;leaf7582</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M67.594,-86.799C67.594,-75.1626 67.594,-59.5479 67.594,-46.2368\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"71.0941,-46.1754 67.594,-36.1754 64.0941,-46.1755 71.0941,-46.1754\"/>\n",
       "<g id=\"a_edge1&#45;label\"><a xlink:title=\"{28.5}\">\n",
       "<text text-anchor=\"middle\" x=\"86.594\" y=\"-57.8\" font-family=\"Times,serif\" font-size=\"14.00\">{28.5}</text>\n",
       "</a>\n",
       "</g>\n",
       "</g>\n",
       "<!-- Average Cube -->\n",
       "<g id=\"node7\" class=\"node\"><title>Average Cube</title>\n",
       "<ellipse fill=\"none\" stroke=\"blue\" cx=\"214.594\" cy=\"-105\" rx=\"61.99\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"214.594\" y=\"-101.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"blue\">Average Cube</text>\n",
       "</g>\n",
       "<!-- Cube&#45;&gt;Average Cube -->\n",
       "<g id=\"edge5\" class=\"edge\"><title>Cube&#45;&gt;Average Cube</title>\n",
       "<path fill=\"none\" stroke=\"red\" d=\"M197.844,-173.799C200.719,-162.163 204.576,-146.548 207.865,-133.237\"/>\n",
       "<polygon fill=\"red\" stroke=\"red\" points=\"211.35,-133.723 210.351,-123.175 204.554,-132.044 211.35,-133.723\"/>\n",
       "<g id=\"a_edge5&#45;label\"><a xlink:title=\"{27, 729, 64, 343, 512, 125, 0, 1, 8, 216}\">\n",
       "<text text-anchor=\"middle\" x=\"227.594\" y=\"-144.8\" font-family=\"Times,serif\" font-size=\"14.00\">{27, ...}</text>\n",
       "</a>\n",
       "</g>\n",
       "</g>\n",
       "<!-- Average Cube&#45;&gt;leaf7574 -->\n",
       "<g id=\"edge4\" class=\"edge\"><title>Average Cube&#45;&gt;leaf7574</title>\n",
       "<path fill=\"none\" stroke=\"black\" d=\"M214.594,-86.799C214.594,-75.1626 214.594,-59.5479 214.594,-46.2368\"/>\n",
       "<polygon fill=\"black\" stroke=\"black\" points=\"218.094,-46.1754 214.594,-36.1754 211.094,-46.1755 218.094,-46.1754\"/>\n",
       "<g id=\"a_edge4&#45;label\"><a xlink:title=\"{202.5}\">\n",
       "<text text-anchor=\"middle\" x=\"237.094\" y=\"-57.8\" font-family=\"Times,serif\" font-size=\"14.00\">{202.5}</text>\n",
       "</a>\n",
       "</g>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Running..."
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Using 2 cached PCollections\n",
       "Executing 8 of 5 transforms."
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Average Cube produced {202.5}"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Cube produced {27, 729, 64, 343, 512, ...}"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Square produced {36, 1, 9, 25, 81, ...}"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "Average Square produced {28.5}"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "average_square = squares | 'Average Square' >> beam.CombineGlobally(AverageFn())\n",
    "average_cube = cubes | 'Average Cube' >> beam.CombineGlobally(AverageFn())\n",
    "result = p.run(False)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python (beam_venv)",
   "language": "python",
   "name": "beam_venv_kernel"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
